package com.example.pagingdemo.paging;

import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import androidx.paging.DataSource;
import androidx.paging.LivePagedListBuilder;
import androidx.paging.PagedList;

/**
 * @author: tuyrt7 on 2020/9/10.
 */
public abstract class AbsViewModel<T> extends ViewModel {

    private LiveData<PagedList<T>> mPagedData;
    private DataSource mDataSource;

    private MutableLiveData<Boolean> boundaryPageData = new MutableLiveData<>();

    public AbsViewModel() {
        //配置PageList
        PagedList.Config config = new PagedList.Config.Builder()
                //分页时，每页item数目
                .setPageSize(PageConfig.PER_PAGE_SIZE)
                //距离底部3个item时自动加载下一页
                .setPrefetchDistance(PageConfig.PRE_SIZE)
                //加载首页数目
                .setInitialLoadSizeHint(PageConfig.INIT_SIZE)
                //列表最大数目 必须时每页的倍数
                .setMaxSize(65535 * PageConfig.PER_PAGE_SIZE)
                //分页时，下一页刷新时占位符，（只有设置 setMaxSize 后才有效）
                .setEnablePlaceholders(false)
                .build();
        //初始化PageList
        mPagedData = new LivePagedListBuilder(mFactory, config)
                .setInitialLoadKey(0)
                .setBoundaryCallback(callback)
                .build();
    }
    PagedList.BoundaryCallback<T> callback = new PagedList.BoundaryCallback<T>() {

        //新提交的PagedList数据为空时,回调此方法
        @Override
        public void onZeroItemsLoaded() {
            boundaryPageData.postValue(false);
        }

        //新提交的PagedList第一条数据被加载到列表时,回调
        @Override
        public void onItemAtFrontLoaded(@NonNull T itemAtFront) {
            boundaryPageData.postValue(true);
        }

        //新提交的PagedList中最后一条数据加载时回调
        @Override
        public void onItemAtEndLoaded(@NonNull T itemAtEnd) {
            super.onItemAtEndLoaded(itemAtEnd);
        }
    };


    public LiveData<PagedList<T>> getPagedData() {
        return mPagedData;
    }

    public DataSource getDataSource() {
        return mDataSource;
    }

    public LiveData<Boolean> getBoundaryPageData() {
        return boundaryPageData;
    }

    DataSource.Factory mFactory = new DataSource.Factory() {
        @NonNull
        @Override
        public DataSource create() {
            if (mDataSource == null || mDataSource.isInvalid()) {
                mDataSource = createDataSource();
            }
            return mDataSource;
        }
    };


    protected abstract DataSource createDataSource();
}
